package com.gcph.zhuoba.main.view;
import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import com.gcph.zhuoba.R;
import com.gcph.zhuoba.main.bean.Ball;
import com.gcph.zhuoba.main.bean.Desk;
import com.gcph.zhuoba.main.bean.Element;
import com.gcph.zhuoba.main.common.Constant;
import com.gcph.zhuoba.util.L;
import com.gcph.zhuoba.util.SocketClient;
import com.gcph.zhuoba.util.TouchUtil;
/**
 * 球桌页面
 */
public class BilliardsDeskView extends SurfaceView implements SurfaceHolder.Callback{
	//定义画笔
	private Paint paint; 		
	//定义画布
	private Canvas canvas = null; 
	private SurfaceHolder sfh = null;
	
	private int move_index=0;
	
	public BilliardsDeskView(Context context){
		super(context);
		initPaint();
		sfh = getHolder();
		sfh.addCallback(this);
	}
	
	@Override
	protected void onDraw(Canvas canvas) {
		L.d( "onDraw");
	}
	
	@Override
	public void surfaceCreated(SurfaceHolder holder) {
		
		L.d( "surfaceCreated");
		
		//获取视图的宽度
		Constant.screenW = getWidth();
		//获取视图的高度
		Constant.screenH = getHeight();
		//球桌和球的缩放比例
		Constant.ratio = Constant.screenH/(Constant.imgDeskH+0.0f);
		
		L.d("BilliardsDeskView screenW=="+Constant.screenW);
		L.d("BilliardsDeskView screenH=="+Constant.screenH);
		L.d("BilliardsDeskView ratio=="+Constant.ratio);
		
		//一个球占的像素数=一个实球按比例应该占的像素数，可推导出球的缩放比例
		//Constant.ballRatio*Constant.imgBallDiameter=Constant.screenH*(Constant.ballH/Constant.deskH)
		Constant.ballRatio= Constant.screenH*(Constant.ballH/Constant.deskH)/Constant.imgBallDiameter;
		
		//原点的偏移量
		Constant.OFFSET_X = Constant.imgDeskFrame*Constant.ratio;
		Constant.OFFSET_Y = Constant.imgDeskFrame*Constant.ratio;
		
		//初始化球袋的真实位置xy
		float[][] bagRealPositions=new float[6][2];
		float[] bagPosition = null;
		for (int i = 0; i < Desk.bagPositions.length; i++) {
			bagPosition = Desk.bagPositions[i];
			float x=bagPosition[0]*Constant.ratio+Constant.OFFSET_X;
			float y=bagPosition[1]*Constant.ratio+Constant.OFFSET_Y;
			bagRealPositions[i]=new float[]{x,y};
		}
		Desk.bagRealPositions= bagRealPositions;
		
		//初始化球桌
		if(Desk.bitmaps.size()==0)
		{
			Desk.bitmaps.add(BitmapFactory.decodeResource(getResources(), R.drawable.common_desk));
			Desk.bmpsPos.add(new float[]{0,0});
		}

		myDraw();
	}
	
	/**
	 * 初始化画笔
	 */
	private void initPaint(){
		paint = new Paint();
		//设置消除锯齿
		paint.setAntiAlias(true);
	}
	
	/**
	 * 画球桌
	 * 备注：切记，在自定SurfaceView中定义的myDraw方法，自定义View（继承自View的子类）中的onDraw方法完全是两码事：
	 * 1）自定义View（继承自View的子类）中的onDraw方法是重写父类的onDraw方法，在调用postInvalidate后会自动回调该onDraw()方法。
	 * 2）此处的drawDesk方法需要手动调用，所以此处故意将方法命名为myDraw，突出为该方法是自己写的，非重写父类的方法 。
	 */
	 public void myDraw() {
		//获取canvas实例
		canvas = sfh.lockCanvas();
		//画桌子及桌子上的球
		Desk.drawSelf(canvas, paint);
		sfh.unlockCanvasAndPost(canvas);
	}
	
	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width,
			int height) {
		L.d( "surfaceChanged");
	}
	
	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		L.d( "surfaceDestroyed");
	}
	
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		int cx=0,cy=0;
		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN:
			// 按下
			cx = (int) event.getX();
			cy = (int) event.getY();
			//选完类型后，即可选目标球
			if(Desk.STEP_FLAG_SELECTED_TYPE == Desk.STEP_FLAG)
			{
				if(selectedBall(cx,cy))
				{
					myDraw();
				}
			}
			
			
			//选完目标球即可选袋
			if(Desk.STEP_FLAG_SELECTED_BALL== Desk.STEP_FLAG)
			{
				//K球和走位教案可选目标袋,还可继续选目标球
				if(Constant.RESOURCE_SMALL_TYPE_KQIU.equals(Desk.RESOURCE_TEACHING_TYPE) || Constant.RESOURCE_SMALL_TYPE_ZOUWEI.equals(Desk.RESOURCE_TEACHING_TYPE))
				{
					if(selectedBall(cx,cy))
					{
						myDraw();
					}
					else if(selectedBag(cx,cy))
					{
						myDraw();
					}
				}
			}
			
			//已选袋，并制作的为K球教案，可以选择要K球的球
			if(Desk.STEP_FLAG_SELECTED_BAG == Desk.STEP_FLAG && Constant.RESOURCE_SMALL_TYPE_KQIU.equals(Desk.RESOURCE_TEACHING_TYPE))
			{
				if(selectedKBall(cx,cy))
				{
					myDraw();
				}
			}
			
			//设置元素
			if(Desk.STEP_FLAG_SELECTED_TYPE == Desk.STEP_FLAG)
			{
				//选择元素
				selectElement(cx,cy);
			}
			
			break;
		case MotionEvent.ACTION_MOVE:
			// 移动
			cx = (int) event.getX();
			cy = (int) event.getY();
			//设置元素位置并向投影端发送元素位置
			setAndSendElementPosition(cx,cy,true);
			break;
		case MotionEvent.ACTION_UP:
			// 移动
			cx = (int) event.getX();
			cy = (int) event.getY();
			
			//向投影端发送元素的最后位置
			sendElementPosition();
			//把选中的元素标识去掉
			Desk.ELEMENT_CURRENT_INDEX=-1;
			break;
		}
		return true;  
	}
	
	/**
	 * 设置元素位置并向投影端发送元素位置
	 */
	public void setAndSendElementPosition(int cx,int cy,boolean isInterval)
	{
		//若处在设置元素步骤中
		if(Desk.STEP_FLAG == Desk.STEP_FLAG_SELECTED_TYPE)
		{
			if(Desk.ELEMENT_CURRENT_INDEX<0 || Desk.ELEMENT_CURRENT_INDEX>=Desk.elementList.size())
			{
				return;
			}
			Desk.elementList.get(Desk.ELEMENT_CURRENT_INDEX).setX(cx);
			Desk.elementList.get(Desk.ELEMENT_CURRENT_INDEX).setY(cy);
			//非调试模式下发送通知给后端
			if(!Constant.IS_DEBUG)
			{
				if(isInterval)
				{
					move_index++;
				}
				//移动时发送移动请求太频繁。
				if(isInterval==false || move_index%5==0)
				{
					int id = Desk.elementList.get(Desk.ELEMENT_CURRENT_INDEX).getId();
					int eType = Desk.elementList.get(Desk.ELEMENT_CURRENT_INDEX).getElementType();
					float x=(Desk.elementList.get(Desk.ELEMENT_CURRENT_INDEX).getX()-Constant.OFFSET_X)/((Constant.imgDeskW-2*Constant.imgDeskFrame)*Constant.ratio);
					float y=(Desk.elementList.get(Desk.ELEMENT_CURRENT_INDEX).getY()-Constant.OFFSET_Y)/((Constant.imgDeskH-2*Constant.imgDeskFrame)*Constant.ratio);
					//float radio = Desk.elementList.get(Desk.ELEMENT_CURRENT_INDEX).getRadius()/((Constant.imgDeskW-2*Constant.imgDeskFrame)*Constant.ratio);
					float radio = Desk.elementList.get(Desk.ELEMENT_CURRENT_INDEX).getRadius();
					if(Constant.RESOURCE_SMALL_TYPE_KQIU.equals(Desk.RESOURCE_TEACHING_TYPE))
					{
						L.d("元素位置x="+x+" y="+y+" radio="+radio);
						String socketData = "{\"method\":\"306\",\"data\":\"YS"+eType+":"+x+","+y+","+radio+","+id+"\"}";
						SocketClient.getInstance().send(socketData);
					}else if(Constant.RESOURCE_SMALL_TYPE_ZOUWEI.equals(Desk.RESOURCE_TEACHING_TYPE))
					{
						String socketData = "{\"method\":\"303\",\"data\":\"YS"+eType+":"+x+","+y+","+radio+","+id+"\"}";
						SocketClient.getInstance().send(socketData);
					}else if(Constant.RESOURCE_SMALL_TYPE_JIEQIU.equals(Desk.RESOURCE_TEACHING_TYPE))
					{
						String socketData = "{\"method\":\"312\",\"data\":\"YS"+eType+":"+x+","+y+","+radio+","+id+"\"}";
						SocketClient.getInstance().send(socketData);
					}else if(Constant.RESOURCE_SMALL_TYPE_FANGSHOU.equals(Desk.RESOURCE_TEACHING_TYPE))
					{
						String socketData = "{\"method\":\"310\",\"data\":\"YS"+eType+":"+x+","+y+","+radio+","+id+"\"}";
						SocketClient.getInstance().send(socketData);
					}
				}
			}
			myDraw();
		}
	}
	
	
	
	/**
	 * 向投影端发送元素的最后位置
	 */
	private void sendElementPosition()
	{
		//若已选中教案类型，即可进行元素的拖动
		if(Desk.STEP_FLAG == Desk.STEP_FLAG_SELECTED_TYPE)
		{
			if(Desk.ELEMENT_CURRENT_INDEX<0 || Desk.ELEMENT_CURRENT_INDEX>=Desk.elementList.size())
			{
				return;
			}
			//非调试模式下发送通知给后端
			if(!Constant.IS_DEBUG)
			{
				int id = Desk.elementList.get(Desk.ELEMENT_CURRENT_INDEX).getId();
				int eType = Desk.elementList.get(Desk.ELEMENT_CURRENT_INDEX).getElementType();
				float x=(Desk.elementList.get(Desk.ELEMENT_CURRENT_INDEX).getX()-Constant.OFFSET_X)/((Constant.imgDeskW-2*Constant.imgDeskFrame)*Constant.ratio);
				float y=(Desk.elementList.get(Desk.ELEMENT_CURRENT_INDEX).getY()-Constant.OFFSET_Y)/((Constant.imgDeskH-2*Constant.imgDeskFrame)*Constant.ratio);
				//float radio = Desk.elementList.get(Desk.ELEMENT_CURRENT_INDEX).getRadius()/((Constant.imgDeskW-2*Constant.imgDeskFrame)*Constant.ratio);
				float radio = Desk.elementList.get(Desk.ELEMENT_CURRENT_INDEX).getRadius();
				
				if(Constant.RESOURCE_SMALL_TYPE_KQIU.equals(Desk.RESOURCE_TEACHING_TYPE))
				{
					L.d("元素位置x="+x+" y="+y+" radio="+radio);
					String socketData = "{\"method\":\"306\",\"data\":\"YS"+eType+":"+x+","+y+","+radio+","+id+"\"}";
					SocketClient.getInstance().send(socketData);
				}else if(Constant.RESOURCE_SMALL_TYPE_ZOUWEI.equals(Desk.RESOURCE_TEACHING_TYPE))
				{
					String socketData = "{\"method\":\"303\",\"data\":\"YS"+eType+":"+x+","+y+","+radio+","+id+"\"}";
					SocketClient.getInstance().send(socketData);
				}
			}
			myDraw();
		}
	}
	
	/**
	 * 选中目标球
	 * @param x
	 * @param y
	 */
	public boolean selectedBall(float x,float y)
	{
		double minDestance = 10000.0;
		double destance = 0.0;
		Ball ball = null;
		Ball minPathBall = null;
		for(int i=0;i<Desk.canInBallList.size();i++){
			ball = Desk.canInBallList.get(i);
			destance = TouchUtil.getPointDistance(x, y, ball.getX(), ball.getY());
			if(destance<minDestance)
			{
				minDestance = destance;
				minPathBall = ball;
			}
		}
		
		//如果是解球或防守,所有球都可选，除了白球。
		if(Constant.RESOURCE_SMALL_TYPE_JIEQIU.equals(Desk.RESOURCE_TEACHING_TYPE) || Constant.RESOURCE_SMALL_TYPE_FANGSHOU.equals(Desk.RESOURCE_TEACHING_TYPE))
		{
			for(int i=0;i<Desk.notCanInballList.size();i++){
				ball = Desk.notCanInballList.get(i);
				if(ball.getNo()!=24){
					destance = TouchUtil.getPointDistance(x, y, ball.getX(), ball.getY());
					if(destance<minDestance)
					{
						minDestance = destance;
						minPathBall = ball;
					}
				}
			}
		}
		//选 中了目标球
		if(minDestance<Constant.ballH*Constant.ballRatio)
		{
			if(null == Desk.selectedBall || !Desk.selectedBall.equals(minPathBall))
			{
				Desk.selectedBall = minPathBall;
				Desk.selectedBag = -1;
				Desk.canInBag = minPathBall.getCanInBag();
				Desk.STEP_FLAG=Desk.STEP_FLAG_SELECTED_BALL;
				
				SocketClient.getInstance().getHandler().sendEmptyMessage(SocketClient.SELECTED_BALL);
				
				//据据教案的类型，发送选中目标球指令
				if(Constant.RESOURCE_SMALL_TYPE_KQIU.equals(Desk.RESOURCE_TEACHING_TYPE))
				{
					SocketClient.getInstance().send("{\"method\":\""+Constant.SOCKET_METHOD_TEACHING_KQIU_SELECTEDBALL+"\",\"data\":\"100:"+minPathBall.getNo()+"\"}");
				}else if(Constant.RESOURCE_SMALL_TYPE_ZOUWEI.equals(Desk.RESOURCE_TEACHING_TYPE))
				{
					SocketClient.getInstance().send("{\"method\":\""+Constant.SOCKET_METHOD_TEACHING_ZOUWEI_SELECTEDBALL+"\",\"data\":\"100:"+minPathBall.getNo()+"\"}");
				}else if(Constant.RESOURCE_SMALL_TYPE_JIEQIU.equals(Desk.RESOURCE_TEACHING_TYPE))
				{
					SocketClient.getInstance().send("{\"method\":\""+Constant.SOCKET_METHOD_TEACHING_JIEQIU_SELECTEDBALL+"\",\"data\":\"100:"+minPathBall.getNo()+"\"}");
				}else if(Constant.RESOURCE_SMALL_TYPE_FANGSHOU.equals(Desk.RESOURCE_TEACHING_TYPE))
				{
					SocketClient.getInstance().send("{\"method\":\""+Constant.SOCKET_METHOD_TEACHING_FANGSHOU_SELECTEDBALL+"\",\"data\":\"100:"+minPathBall.getNo()+"\"}");
				}
				return true;
			}
		}
		return false;
	}
	
	/**
	 * 选择要K的球
	 * @param x
	 * @param y
	 */
	public boolean selectedKBall(float x,float y)
	{
		double minDestance = 10000.0;
		double destance = 0.0;
		Ball ball = null;
		Ball minPathBall = null;
		List<Ball> allList = new ArrayList<Ball>();
		allList.addAll(Desk.notCanInballList);
		allList.addAll(Desk.canInBallList);
		for(int i=0;i<allList.size();i++){
			
			ball = allList.get(i);
			if(!ball.equals(Desk.selectedKBall) && ball.getNo()!=24 && !ball.equals(Desk.selectedBall))
			{
				destance = TouchUtil.getPointDistance(x, y, ball.getX(), ball.getY());
				if(destance<minDestance)
				{
					minDestance = destance;
					minPathBall = ball;
				}
			}
		}
		//选 中了要K的球
		if(minDestance<Constant.ballH*Constant.ballRatio)
		{
			if(null == Desk.selectedKBall || !Desk.selectedKBall.equals(minPathBall))
			{
				Desk.selectedKBall = minPathBall;
				Desk.STEP_FLAG = Desk.STEP_FLAG_SELECTED_KBALL;
				
				//发送通知给后端
				SocketClient.getInstance().send("{\"method\":\"309\",\"data\":\"101:"+minPathBall.getNo()+"\"}");
				SocketClient.getInstance().getHandler().sendEmptyMessage(SocketClient.SELECTED_KBALL);
				return true;
			}
		}
		return false;
	}
	
	/**
	 * 选择要进的袋 
	 * @param x
	 * @param y
	 */
	public boolean selectedBag(float x,float y)
	{
		double destance = 0.0;
		if(null == Desk.canInBag)
		{
			return false;
		}
		boolean flag = false;
		float bagPositionX = 0f;
		float bagPositionY = 0f;
		for(int i=0;i<Desk.canInBag.length;i++){
			bagPositionX=Desk.bagRealPositions[Desk.canInBag[i]][0];
			bagPositionY=Desk.bagRealPositions[Desk.canInBag[i]][1];
			destance = TouchUtil.getPointDistance(x, y, bagPositionX,bagPositionY);
			//选 中了球袋
			if(destance<Constant.ballH*Constant.ballRatio*2)
			{
				Desk.selectedBag = Desk.canInBag[i];
				flag = true;
				
				Desk.STEP_FLAG = Desk.STEP_FLAG_SELECTED_BAG;
				SocketClient.getInstance().getHandler().sendEmptyMessage(SocketClient.SELECTED_BAG);
				
				//据据教案的类型，发送选中目标球指令
				if(Constant.RESOURCE_SMALL_TYPE_KQIU.equals(Desk.RESOURCE_TEACHING_TYPE))
				{
					SocketClient.getInstance().send("{\"method\":\""+Constant.SOCKET_METHOD_TEACHING_KQIU_SELECTEDBAG+"\",\"data\":\"qd:"+Desk.selectedBag+"\"}");
				}else if(Constant.RESOURCE_SMALL_TYPE_ZOUWEI.equals(Desk.RESOURCE_TEACHING_TYPE))
				{
					SocketClient.getInstance().send("{\"method\":\""+Constant.SOCKET_METHOD_TEACHING_ZOUWEI_SELECTEDBAG+"\",\"data\":\"qd:"+Desk.selectedBag+"\"}");
				}
				break;
			}
		}
		
		return flag;
	}
	
	
	/**
	 * 选择要移动的元素
	 * @param x
	 * @param y
	 */
	public boolean selectElement(float x,float y)
	{
		//距离
		double destance = 0.0;
		
		boolean flag = false;
		float elementPositionX = 0f;
		float elementPositionY = 0f;
		Element tempElement = null;
		for(int i=0;i<Desk.elementList.size();i++){
			tempElement = Desk.elementList.get(i);
			elementPositionX=tempElement.getX();
			elementPositionY=tempElement.getY();
			destance = TouchUtil.getPointDistance(x, y, elementPositionX,elementPositionY);
			//选 中了元素
			if(destance<=Constant.imgBallDiameter*Constant.ballRatio*2)
			{
				Desk.ELEMENT_CURRENT_INDEX = i;
				
				flag = true;
				break;
			}
		}
		
		return flag;
	}

	public SurfaceHolder getSfh() {
		return sfh;
	}

	public Canvas getCanvas() {
		return canvas;
	}
}